#pragma once
namespace WX
{
	template<class T>
	struct list_node
	{
		struct list_node* _next;
		struct list_node* _prev;
		T _data;

		list_node(const T& x = T())
			:_next(nullptr)
			,_prev(nullptr)
			,_data(x)
		{}

	};

	template<class T, class Ref, class Ptr>
	struct list_iterator
	{
		typedef list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> Sel;

		Node* _node;

		list_iterator( Node* node)
			:_node(node)
		{}

		//T& operator*()
		//{
		//	return _node->_data;
		//}

		Ref operator*()
		{
			return _node->_data;
		}

		//T* operator->()
		//{
		//	return &_node->_data;
		//}

		Ptr operator->()
		{
			return &_node->_data;
		}

		Sel& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		bool operator!=(const Sel it )
		{
			return _node != it._node;
		}

		bool operator==(const Sel it)
		{
			return _node == it._node;
		}

	};

	template<class T>
	class list
	{
		public:
			typedef list_node<T> Node;
			//typedef list_iterator iterator;
			typedef list_iterator<T, T&, T*> iterator;
			typedef list_iterator<T, const T&, const T*> const_iterator;

			list()
			{
				_head = new Node;
				_head->_next = _head;
				_head->_prev = _head;
			}

			iterator begin()
			{
				return iterator(_head->_next);
			}

			iterator end()
			{
				return iterator(_head);
			}

			const_iterator begin() const 
			{
				return const_iterator(_head->_next);
			}	
			
			const_iterator end() const 
			{
				return const_iterator(_head);
			}

			void push(const T& x)
			{
				Node* newnode = new Node(x);

				Node* tail = _head->_prev;
				newnode->_prev = tail;
				tail->_next = newnode;
				newnode->_next = _head;
				_head->_prev = newnode;
			}

		private:
			Node* _head;
	};

}